#ifndef     __MAKE_ICE_TASK_H
#define     __MAKE_ICE_TASK_H

#include "../rtos/thread.h"
#include "../utils/object.h"
#include "../rtos/message_queue.h"
#include "../rtos/event_flags.h"

namespace ice_task {

class MakeIceTask : public rtos::Thread<MakeIceTask, 1024, osPriorityHigh1> {

public:
    enum class State : uint8_t {
        IDLE = 0,
        WORK_BEGIN = 1,
        WORK = 2,
        WORK_END = 3,
        STOP = 4,
        TIMEOUT = 5,
        FAIL = 6,
        STIR = 7,
    };

    static constexpr uint32_t MAKE_ICE_TIMEOUT = 150 * 60 * 1000;

    static constexpr uint32_t RUN_STIR_COMPR_DELAY = 10 * 1000;
    static constexpr uint32_t STOP_STIR_COMPR_DELAY = 20 * 1000;
    static constexpr uint32_t RESET_STIR_COMPR_DELAY = 20 * 1000;

    static constexpr uint32_t FLAG_STOP = 0x01;

    void init_start();

    void run();

    void idle() {
        m_mq.post(State::IDLE);
    }

    void stop() {
        m_flags.clr_flags(FLAG_STOP);
        m_mq.post(State::STOP);
        m_flags.wait_any_flags(FLAG_STOP);
    }

    inline uint8_t state() { return static_cast<uint8_t>(m_state); }

private:
    bool wait(uint32_t timeout = osWaitForever) { return m_mq.poll(m_state, timeout) == osOK; }

    void do_idle();
    void do_work_begin();
    void do_work();
    void do_work_end();
    void do_timeout();
    void do_stop();
    void do_stir();

    uint32_t m_stir_compr_delay = RESET_STIR_COMPR_DELAY;
    State m_state = State::IDLE;
    rtos::lazy::MessageQueue<State, 2> m_mq;
    rtos::lazy::EventFlags m_flags;
};

extern MakeIceTask makeIceTask;

}

#endif
